package studio.xiaoyun.security.auth;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import studio.xiaoyun.core.dao.PermissionDao;
import studio.xiaoyun.core.dao.RoleDao;
import studio.xiaoyun.core.dao.UserDao;
import studio.xiaoyun.core.pojo.PermissionDO;
import studio.xiaoyun.core.pojo.RoleDO;
import studio.xiaoyun.core.pojo.UserDO;

import java.util.List;
import java.util.Optional;

public class AuthRealm extends AuthorizingRealm {
    private UserDao userDao;
    private RoleDao roleDao;
    private PermissionDao permissionDao;

    public RoleDao getRoleDao() {
        return roleDao;
    }

    public void setRoleDao(RoleDao roleDao) {
        this.roleDao = roleDao;
    }

    public PermissionDao getPermissionDao() {
        return permissionDao;
    }

    public void setPermissionDao(PermissionDao permissionDao) {
        this.permissionDao = permissionDao;
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String userId = (String) pc.fromRealm(this.getName()).iterator().next();
        //获得用户的所有权限
        List<PermissionDO> permissions = permissionDao.listPermissionByUserId(userId, null);
        for (PermissionDO permission : permissions) {
            info.addStringPermission(permission.getName().name());
        }
        //获得用户的所有角色
        List<RoleDO> roles = roleDao.listRoleByUserId(userId, null);
        for (RoleDO role : roles) {
            info.addRole(role.getName());
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        Optional<UserDO> user = userDao.getUserByEmail(token.getUsername());
        if (!user.isPresent()) { //如果根据邮箱无法找到用户，则根据用户名查找
            user = userDao.getUserByName(token.getUsername());
        }
        if (!user.isPresent()) {
            throw new UnknownAccountException();  //用户名或者邮箱不存在
        }
        UserDO userInfo = user.get();
        //检查用户的状态
        switch (userInfo.getStatus()) {
            case NORMAL:
                break;
            case DELETED:
                throw new DisabledAccountException();  //账号不可用
            default:
                throw new AccountException("无法识别的参数:" + userInfo.getStatus());  //内部错误
        }
        //检查用户类型
        if(!userInfo.getUserType().equals(token.getType())){
            throw new UnknownAccountException();
        }
        return new SimpleAuthenticationInfo(userInfo.getUserId(), userInfo.getPassword(), this.getName());
    }

}
